<?php
// Copyright 2012 @Wondershare.com
// $Id: func.class.php 24762 2012-09-03 14:21:04Z xuwh $
class func
{
    static function _h ($str)
    {
        return htmlspecialchars($str);
    }
    static function check_login ($redirect = NULL)
    {
        self::check_login_exists();
        if (empty($_SESSION['user_name'])) {
            $url = func::get_cfg('url_login', '/account/login');
            if ($redirect)
                $url .= "?redirect=" . urlencode($redirect);
            header("Location: {$url}");
            exit();
        }
    }
    static function reg_email_is_blocked ($email)
    {
        static $config = NULL;
        if (! isset($config))
            $config=include "config/reg_block_emails.php";
        if (empty($config) || !$email)
            return FALSE;
        $host=strstr($email,'@');
        return in_array($host, $config);
    }
    static function check_login_exists ()
    {
        if (isset($_SESSION['user_id']))
            return TRUE;
        func::start_session();
        $cookie_name = func::get_cfg("cookie_name_online");
        $cookie = isset($_COOKIE[$cookie_name]) ? $_COOKIE[$cookie_name] : false;
        if ($cookie && ! isset($_SESSION['provider'])) {
            $sign_str = func::authcode($cookie, "DECODE");
            $sess = explode("\t", $sign_str);
            $_SESS = array('user_id' => $sess[0], 'user_name' => $sess[1], 
            'email' => $sess[2], 'nickname' => $sess[3]);
            $_SESSION = array_merge($_SESSION, $_SESS);
            return TRUE;
        } else {
            return FALSE;
        }
    }
    /**
     * description...
     *
     * @access global
     * @param $to_long bool       	
     * @return void
     */
    static function get_ip ($to_long = FALSE)
    {
        static $ip = NULL;
        if (! isset($ip)) {
            $headers = array('HTTP_FORWARDED', 'HTTP_FORWARDED_FOR', 
            'HTTP_X_FORWARDED', 'HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP', 
            'REMOTE_ADDR');
            foreach ($headers as $header) {
                if (isset($_SERVER[$header]) &&
                 strcasecmp($_SERVER[$header], 'unknown')) {
                    $ip = $_SERVER[$header];
                    break;
                }
            }
        }
        if ($to_long) {
            return bindec(decbin(ip2long($ip)));
        } else {
            return (FALSE === ip2long($ip)) ? 'unknown' : $ip;
        }
    }
    /**
     * 判断是否为ajax调用
     */
    public static function is_ajax ()
    {
        return (isset($_SERVER['HTTP_X_REQUESTED_WITH']) and
         strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest');
    }
    /**
     * 渲染视图
     * @param string $view
     * @param array $data
     * @param string $lang
     */
    static function load_view ($view, $data = array())
    {
        $view = "views/{$view}.php";
        $_is_production=(func::get_cfg('environ') === 'production');
    	$lang = 'en-us';
        if (defined('LANG'))$lang = LANG;
        $template_cache_dir = APP_PATH . "cache/template/{$lang}";
        $_cpl_file = "{$template_cache_dir}/{$view}";
        if (! is_file($_cpl_file) || !$_is_production) {
            $complier = new View_Parser(array('res_dir_prefix' => 'res', 'clear_blanks' => FALSE, 'res_base_url' => func::get_cfg('res_base_url')));
            $templates = $complier->compile($view, $template_cache_dir);
        }
        extract($data, EXTR_OVERWRITE);
        include ($_cpl_file);
    }
    /**
     * 开发环境资源访问地址
     *
     * @param $res_server string
     * 资源主机域名
     */
    static function get_res_url_dev ($res_server = 'res.ws-game.com')
    {
        $host = $_SERVER['HTTP_HOST'];
        $pos = strrpos($host, '.');
        $dev_site = basename(SITE_PATH);
        $developer = substr($host, $pos + 1);
        return "http://{$res_server}.{$developer}/{$dev_site}/";
    }
    /**
     * 获取config的配置信息
     *
     * @param $db string       	
     */
    static function get_cfg ($key = NULL, $default = NULL)
    {
        static $config = NULL;
        if (! $config) {
            $config = include 'config/config.inc.php';
            @include 'config/config.local.inc.php'; // 使用local重载config配置
        }
        if ($key === NULL)
            return $config;
        return (isset($config[$key])) ? $config[$key] : $default;
    }
    /**
     * 启动session
     *
     * @param $auto boolean
     * 为FALSE根据cookie判断自动开启,不带参数则开启
     * @param $restart boolean
     * 重新开启session
     */
    static function start_session ($auto = FALSE, $restart = FALSE)
    {
        static $started = NULL;
        if ($started) {
            if (! $restart)
                return TRUE;
            session_regenerate_id(TRUE);
            session_start();
            return TRUE;
        }
        $cfg = func::get_cfg('session');
        if (! empty($cfg['save_handler']))
            ini_set('session.save_handler', $cfg['save_handler']);
        if (! empty($cfg['save_path']))
            session_save_path($cfg['save_path']);
        if (! empty($cfg['session_name']))
            session_name($cfg['session_name']);
        if (! empty($cfg['cookie_params']))
            call_user_func_array('session_set_cookie_params', 
            $cfg['cookie_params']);
        if (! $auto) {
            session_start();
            $started = TRUE;
        } else {
            if (isset($_COOKIE[session_name()])) {
                session_start();
                $started = TRUE;
            }
        }
    }
    /**
     * 销毁 Session
     */
    static function destroy_session ()
    {
        if(session_id())
        {
	        session_unset();
	        session_destroy();
	        session_write_close();
	        $cookie_name = func::get_cfg("cookie_name_online");
	        if (isset($_COOKIE[$cookie_name]))setcookie($cookie_name, "", time() - 3600 * 10 * 1000, "/");
	        if (isset($_COOKIE[session_name()]))setcookie(session_name(), '', time() - 42000, '/');
        }
    }
    /**
     * 获取DB的连接实例
     *
     * @param $name String       	
     */
    static function get_db ($name = 'default')
    {
        static $instances = array();
        if (! isset($instances[$name])) {
            $configs = func::get_cfg('db');
            if (! isset($configs[$name]))
                return FALSE;
            $cfg = $configs[$name];
            $obj = new dba($cfg['dsn'], $cfg['user'], $cfg['password'], 
            $cfg['options']);
            if ($obj)
                $instances[$name] = $obj;
        }
        return $instances[$name];
    }
    /**
     * 取锁
     * 
     * @param $name string
     */
    static function get_lock ($name = 'default')
    {
        static $instances = array();
        if (! isset($instances[$name])) {
            $configs = func::get_cfg('lock');
            if (! isset($configs[$name]))
                return FALSE;
            $cfg = $configs[$name];
            $class = "Lock_Driver_{$cfg['driver']}";
            $obj = new $class($cfg);
            $instances[$name] = $obj;
        }
        return $instances[$name];
    }
    /**
     * 显示消息的函数
     *
     * @access global
     * @param $msg string
     * 消息
     * @param $url string
     * 返回的URL
     * @param $is_ok bool       	
     * @return void
     */
    static function showmessage ($msg, $url = '', $is_ok = true, $title = NULL)
    {
        $data = array('url_forward' => $url ? $url : NULL, 'page_nav' => '', 
        'title' => $title, 'message' => $msg, 'is_ok' => $is_ok);
        func::load_view('showmessage', $data);
        exit();
    }
    /**
     * 显示错误系想你
     *
     * @param $errors unknown_type       	
     * @param $descs unknown_type       	
     * @param $type unknown_type       	
     * @param $title unknown_type       	
     */
    static function show_error ($errors, $descs = array(), $type = "Error", 
    $title = "The Following Error Occurred: ")
    {
        // $data['url_forward'] = ($url)?$url:NULL;
        if (! is_array($errors))
            $errors = (array) $errors;
        if (! is_array($descs))
            $descs = (array) $descs;
        $data['errors'] = $errors;
        $data['descs'] = $descs;
        $data['type'] = $type;
        $data['title'] = $title;
        func::load_view('show-error', $data);
        exit();
    }
    /**
     * 分发 Action
     */
    static function dispatch_action ()
    {
        $action = rtrim($_GET['action'], '/');
        $action_func = "action_{$action}";
        is_callable($action_func) ? $action_func() : action_index();
    }
    /**
     * 根据域名自动截取根域，以避免配置需要写死
     */
    static function get_root_domain ($level = 2)
    {
        $domain = NULL;
        $host = empty($_SERVER['HTTP_HOST']) ? NULL : $_SERVER['HTTP_HOST'];
        if ($host) {
            $arr = explode('.', $host);
            if (count($arr) > 1) {
                $arr = array_splice($arr, $level * (- 1));
                $domain = '.' . implode('.', $arr);
            } else {
                $domain = ".{$host}";
            }
        }
        return $domain;
    }
    /**
     * 获取货币符号
     */
    static function get_currency_symbol ($currency = 'USD')
    {
        static $currency_config = array();
        if (! $currency_config)
            $currency_config = @include 'config/currency.config.php';
        return isset($currency_config[$currency]) ? $currency_config[$currency] : $currency;
    }
    /**
     * 获取USD对应要转换的货币汇率
     *
     * @param $to String
     * 要转换的汇率
     * @param $from String
     * 默认为USD
     */
    static function get_rate ($form, $to = 'USD')
    {
        static $config = array();
        $form = strtoupper($form);
        $to = strtolower($to);
        if (! $config)
            $config = @include "config/currency_{$to}.php";
        return isset($config[$form]) ? $config[$form] : FALSE;
    }
    /**
     * 用户信息加密解密函数
     *
     * 待加密内容用/t分割
     *
     * @return String 加密或解密字符串
     * @param $string String
     * 待加密或解密字符串
     * @param $operation String
     * 操作类型定义 DECODE=解密 ENDODE=加密
     * @param $key String
     * 加密算子
     */
    static function authcode ($string, $operation, $key = 'wondershare')
    {
        /**
         * 获取密码算子,如未指定，采取系统默认算子
         * 默认算子是论坛授权码和用户浏览器信息的md5散列值
         * $GLOBALS['discuz_auth_key']----全局变量
         * 取值为:md5($_DCACHE['settings']['authkey'].$_SERVER['HTTP_USER_AGENT'])
         * $_DCACHE['settings']['authkey']是论坛安装时生成的15位随机字符串
         */
        $key = md5($key ? $key : $GLOBALS['discuz_auth_key']);
        $key_length = strlen($key);
        /**
         * 如果解密，先对密文解码
         * 如果加密,将密码算子和待加密字符串进行md5运算后取前8位
         * 并将这8位字符串和待加密字符串连接成新的待加密字符串
         */
        $string = $operation == 'DECODE' ? base64_decode($string) : substr(
        md5($string . $key), 0, 8) . $string;
        $string_length = strlen($string);
        $rndkey = $box = array();
        $result = '';
        /**
         * 初始化加密变量,$rndkey和$box
         */
        for ($i = 0; $i <= 255; $i ++) {
            $rndkey[$i] = ord($key[$i % $key_length]);
            $box[$i] = $i;
        }
        /**
         * $box数组打散供加密用
         */
        for ($j = $i = 0; $i < 256; $i ++) {
            $j = ($j + $box[$i] + $rndkey[$i]) % 256;
            $tmp = $box[$i];
            $box[$i] = $box[$j];
            $box[$j] = $tmp;
        }
        /**
         * $box继续打散,并用异或运算实现加密或解密
         */
        for ($a = $j = $i = 0; $i < $string_length; $i ++) {
            $a = ($a + 1) % 256;
            $j = ($j + $box[$a]) % 256;
            $tmp = $box[$a];
            $box[$a] = $box[$j];
            $box[$j] = $tmp;
            $result .= chr(
            ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
        }
        if ($operation == 'DECODE') {
            if (substr($result, 0, 8) ==
             substr(md5(substr($result, 8) . $key), 0, 8)) {
                return substr($result, 8);
            } else {
                return '';
            }
        } else {
            return str_replace('=', '', base64_encode($result));
        }
    }
    /**
     * 解析剩余$_GET中/a/b/c....类似的未捕获的串，解析为arg4,arg5,arg6...
     *
     * @param $start_index integer       	
     */
    static function parse_remain_args ($start_index = 1)
    {
        foreach ($_GET as $k => $v) {
            if ($k[0] === '/') {
                unset($_GET[$k]);
                $args = explode('/', trim($k, '/'));
                foreach ($args as $v2) {
                    $_GET["arg{$start_index}"] = $v2;
                    $start_index ++;
                }
            }
        }
    }
    /**
     * 随机字符串
     *
     * @param $length integer       	
     */
    static function random ($length)
    {
        $hash = "";
        $chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
        $max = strlen($chars) - 1;
        mt_srand((double) microtime() * 1000000);
        for ($i = 0; $i < $length; $i ++) {
            $hash .= $chars[mt_rand(0, $max)];
        }
        return $hash;
    }
    static function form_back ()
    {
        header("Pragma: public");
        header("Expires: 0");
        header("Cache-Control: private");
    }
}